package com.feishi.core.media.javacv;

import com.feishi.core.media.javacv.util.OpenCvUtil;

import java.nio.ByteBuffer;
import java.util.*;

import static org.bytedeco.javacpp.Loader.sizeof;
import static org.bytedeco.javacpp.opencv_core.*;

import static org.bytedeco.javacpp.opencv_imgcodecs.*;
import static org.bytedeco.javacpp.opencv_imgproc.*;
import static org.bytedeco.javacpp.opencv_imgproc.cvCvtColor;
import static org.bytedeco.javacpp.opencv_imgproc.threshold;

/**
 * @version 1.0
 * @auth caixq
 * @time 18-5-29 17:15
 **/
public class SplitImg {

    public static void main(String[] args) {



        IplImage   pImg_test = cvLoadImage("/home/caixq/Desktop/test1.png",1);;
        ByteBuffer buffer=pImg_test.createBuffer();
        byte[] bb=new byte[buffer.remaining()];
        byte[] bout=new byte[buffer.remaining()];
        buffer.get(bb);//获取byte数据

        int width=pImg_test.width();
        int height=pImg_test.height();
        int widthStep=pImg_test.widthStep();
        int nchannal=pImg_test.nChannels();

        List<Color> colors=new ArrayList<>();
        Map<String,Integer> map=new HashMap<>();
        int minCount=1;
        int size=5;
        int r=40;
        for(int y=0;y<height;y++){
            for(int x=0;x<width;x++){
                int index=widthStep*y+nchannal*x;

                System.out.println();
                Color color=new Color(bb[index+0],bb[index+1],bb[index+2]);

                String key=color.toColorString();
                if(map.get(key)==null){
                    map.put(key,0);
                }
                int num=map.get(key)+1;
                map.put(key,map.get(key)+1);
                color.num=num;

                if(colors.size()>=size){
                    if(!colors.contains(color)){
                        if(num>minCount){
                            for (Color c : colors) {
                                c.num=map.get(c.toColorString());
                            }
                            Collections.sort(colors);
                            colors.remove(0);
                            colors.add(color);
                            minCount=num;
                        }
                    }
                }else{
                    if(!colors.contains(color)){
                        colors.add(color);
                    }
                }

            }
        }
        System.out.println(colors.size());
        System.out.println(colors);
        List<Integer> list=new ArrayList();
        list.addAll(map.values());

        Collections.sort(list);
        List list1=new ArrayList();
        for (int i = list.size()-size; i < list.size(); i++) {

            list1.add(list.get(i));
        }
        System.out.println(list1);
        ((ByteBuffer)pImg_test.createBuffer()).put(bb);
        imwrite("/home/caixq/Desktop/testTmp.png",new Mat(pImg_test));
        int t=0;
        for (Color color : colors) {
            for(int y=0;y<height;y++){
                for(int x=0;x<width;x++){
                    int index=widthStep*y+nchannal*x;

                    Color c=new Color(bb[index+0],bb[index+1],bb[index+2]);
                    if(color.equals(c)){
                        bout[index]=bb[index];
                        bout[index+1]=bb[index+1];
                        bout[index+2]=bb[index+2];
                    }else {
                        bout[index]= (byte) (256-color.r);
                        bout[index+1]= (byte) (256-color.g);
                        bout[index+2]= (byte) (256-color.b);
                    }
                }
            }
            IplImage out=new IplImage();
            ByteBuffer bf=pImg_test.createBuffer();
            bf.clear();
            bf.put(bout);
//            ((ByteBuffer)pImg_test.createBuffer()).put(bb);
            imwrite("/home/caixq/Desktop/testA"+t+++".png",new Mat(pImg_test));
        }


    }
}
class Color implements Comparable<Color>{
    int r;
    int g;
    int b;
    int num;

    public Color(byte r, byte g, byte b) {
        this.r = Byte.toUnsignedInt(r);
        this.g = Byte.toUnsignedInt(g);
        this.b = Byte.toUnsignedInt(b);
    }

    @Override
    public int compareTo(Color o) {
        return num-o.num;
    }

    @Override
    public boolean equals(Object obj) {
        Color o= (Color) obj;
        return o.r/10==r/10 && o.g/10==g/10 && o.b/10==b/10;
    }

    @Override
    public int hashCode() {
        return r/10*256*256+g/10*256+b/10;
    }

    @Override
    public String toString() {
        return "Color{" +
                "r=" + r +
                ", g=" + g +
                ", b=" + b +
                ", num=" + num +
                '}';
    }

    public String toColorString() {
        return hashCode()+"";
    }
}